import React, { useEffect, useRef, useState } from 'react'

function ProcessCircle({ percent = 80, width = 64, lineWidth = 10, color = 'rgb(0, 255, 0)', gradient = { from: 'rgb(255, 0, 0)', to: 'rgb(0, 255, 0)' } }) {
  const canvasRef = useRef<null | HTMLCanvasElement>(null)
  const ctxRef = useRef<null | CanvasRenderingContext2D>(null)
  const ctxReact = useRef<any>(null)
  const initCanvas = () => {
    if (!canvasRef.current) return

    canvasRef.current.width = width + 10
    canvasRef.current.height = width + 10
    ctxRef.current = canvasRef.current.getContext('2d') as CanvasRenderingContext2D

    // 初始的一些值
    const center = {
      x: canvasRef.current.width / 2,
      y: canvasRef.current.height / 2,
      r: (width - lineWidth * 2) / 2,
    }
    ctxReact.current = center

    const ctx = ctxRef.current
    ctx.strokeStyle = color
    ctx.lineWidth = lineWidth

    // 绘制渐变色
    if (gradient.from) {
      getGradient()
      return
    }

    // 普通绘制
    const endDeg = 1.5 * Math.PI * percent / 100
    ctx.beginPath()
    ctx.arc(center.x, center.y, center.r, -Math.PI / 2, endDeg)
    ctx.stroke()
    ctx.closePath()

    // 绘制圆点
    ctx.beginPath()
    ctx.lineCap = 'round'
    ctx.strokeStyle = getColor(1)
    ctx.arc(center.x, center.y, center.r, endDeg, endDeg)
    ctx.stroke()
    ctx.closePath()

  }

  // 绘制渐变颜色
  function getGradient() {
    const stepDeg = 2 * Math.PI / 100
    const ctx = ctxRef.current as CanvasRenderingContext2D
    const center = ctxReact.current
    let startDeg = -Math.PI / 2
    let endDeg = 0
    for (let i = 0; i <= percent; i++) {
      const rage = i / percent
      ctx.beginPath()
      endDeg = startDeg + stepDeg
      ctx.strokeStyle = getColor(rage)
      ctx.arc(center.x, center.y, center.r, startDeg, endDeg)
      ctx.stroke()
      ctx.closePath()
      startDeg += stepDeg
    }
    // 绘制圆点
    ctx.beginPath()
    ctx.lineCap = 'round'
    ctx.strokeStyle = getColor(1)
    ctx.arc(center.x, center.y, center.r, endDeg, endDeg)
    ctx.stroke()
    ctx.closePath()
  }
  // 根据进度获取当前渐变颜色值
  /**
   * 
   * @param {number} rate 0-1的小数 
   */
  function getColor(rate: number) {
    // TODO 颜色值需要判断是否可用，并转成rgb形式
    // TODO 兼容rgba
    const [sr, sg, sb] = (gradient.from.match(/rgb\((\s*\d+),(\s*\d+),(\s*\d+)\)/i) as RegExpMatchArray).slice(1, 4).map(Number)
    const [er, eg, eb] = (gradient.to.match(/rgb\((\s*\d+),(\s*\d+),(\s*\d+)\)/i) as RegExpMatchArray).slice(1, 4).map(Number)

    const diffR = er - sr
    const diffG = eg - sg
    const diffB = eb - sb

    const color = `rgb(${Math.ceil(sr + diffR * rate)}, ${Math.ceil(sg + diffG * rate)}, ${Math.ceil(sb + diffB * rate)})`
    return color
  }

  useEffect(() => {
    if (canvasRef.current) {
      initCanvas()
    }
  }, [])
  return (
    <div>
      <canvas width={width + 10} height={width + 10} ref={canvasRef}></canvas>
    </div>
  )
}

export default ProcessCircle